﻿using com.nm.Cache;
using com.nm.library;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

// ReSharper disable once CheckNamespace
namespace com.nm
{
    /// <summary>
    /// 维护在线用户列表
    /// </summary>
    public static class OnlineUsers
    {
        private const string CACHE_KEY = "online-users:";
        private const string CACHE_KEY_OPENID = CACHE_KEY + "openid:";
        private const string CACHE_KEY_CUSID = CACHE_KEY + "cusid:";

        private static void AddUser(OnlineUser user)
        {
            if (HttpContext.Current == null || HttpContext.Current.Session == null) return;
            RedisCache.AddObject(CACHE_KEY_CUSID + user.CusID, user, HttpContext.Current.Session.Timeout);
        }

        private static void RemoveUser(OnlineUser user)
        {
            RedisCache.Remove(CACHE_KEY_CUSID + user.CusID);
        }

        private static void RemoveUser(string openId)
        {
            if (RedisCache.Exists("openid2userid:" + openId))
            {
                var cusId = (int)RedisCache.Get("openid2userid:" + openId);
                RedisCache.Remove("openid2userid:" + openId);
                RemoveUser(cusId);
            }
            RedisCache.Remove(CACHE_KEY_OPENID + openId);
        }

        private static void RemoveUser(int cusId)
        {
            if (RedisCache.Exists("userid2openid:" + cusId))
            {
                var openid = (string)RedisCache.Get("userid2openid:" + cusId);
                RedisCache.Remove("userid2openid:" + cusId);
                RemoveUser(openid);
            }
            RedisCache.Remove(CACHE_KEY_CUSID + cusId);
        }

        public static string GetToken()
        {
            var guid = Guid.NewGuid();
            //RedisCache.Add(guid.ToString(), UserInfo.OpenID, 30);
            RedisCache.Add(guid.ToString(), UserInfo.CusIDInt, 30);
            return guid.ToString();
        }

        public static string GetAnonymousToken(string Name)
        {
            var guid = Guid.NewGuid();
            RedisCache.Add("N:" + guid.ToString(), Name, 3000);
            return "N:" + guid.ToString();
        }

        /// <summary>
        /// 把当前用户添加到在线用户列表
        /// </summary>
        public static void AddAndRefresh()
        {
            var key = CACHE_KEY_CUSID + UserInfo.UserID;
            var exists = RedisCache.Exists(key);
            OnlineUser user = null;
            if (!exists)
            {
                var cusType = 0;
                int.TryParse(UserInfo.CusType, out cusType);
                user = new OnlineUser
                {
                    CusID = UserInfo.CusIDInt,
                    OpenID = UserInfo.UserID,
                    UserName = UserInfo.UserName,
                    LoginDate = DateTime.Now,
                    RefreshTime = DateTime.Now,
                    CusType = cusType
                };
                Log.WriteLog("登记在线用户：" + user.UserName);
            }
            else
            {
                user = RedisCache.Get<OnlineUser>(key);
                user.RefreshTime = DateTime.Now;
                Log.WriteLog("刷新在线用户：" + user.UserName);
            }
            AddUser(user);
        }

        /// <summary>
        /// 移除在线用户信息
        /// </summary>
        public static void Remove()
        {
            if (Count < 1)
            {
                return;
            }
            RemoveUser(UserInfo.CusIDInt);
        }

        /// <summary>
        /// 在线用户数量
        /// </summary>
        public static long Count => RedisCache.Count(CACHE_KEY_CUSID + "*");

        /// <summary>
        /// 获取在线用户列表（最近有刷新的排前）
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        public static List<OnlineUser> GetUsers(int count = 10)
        {
            var userList = RedisCache.GetList<OnlineUser>(CACHE_KEY_CUSID + "*", count);

            return userList.OrderByDescending(item => item.RefreshTime).Take(count).ToList();
        }
    }

    [Serializable]
    public class OnlineUser
    {
        public int CusID { get; set; }
        public string OpenID { get; set; }
        public string UserName { get; set; }
        public DateTime LoginDate { get; set; }
        public DateTime RefreshTime { get; set; }
        public string IPAddress { get; set; }

        /// <summary>
        /// 用户VIP等级
        /// </summary>
        public int CusType { get; set; }

        public string OnlineTime
        {
            get
            {
                var st = DateTime.Now - this.LoginDate;
                return st.Hours > 0
                    ? $"{st.Hours:D}小时{st.Minutes:D}分{st.Seconds:D}秒"
                    : (st.Minutes > 0
                        ? $"{st.Minutes:D}分{st.Seconds:D}秒"
                        : $"{st.Seconds:D}秒");
            }
        }
    }
}